import fs from "fs"
import path from "path"

export interface DirectoryItem {
  text: string
  collapsed?: true
  link?: string
  items?: DirectoryItem[]
}

export interface DirectoryTree extends DirectoryItem {
  items: DirectoryItem[]
}

const prefix = "/blogItem/"

/**
 * 从文件名中提取罗马数字前缀，并将其转换为整数。
 * @param fileName 文件名
 * @returns 如果文件名包含有效的罗马数字前缀，则返回对应的整数；否则返回 Infinity。
 */
function extractRomanPrefix(fileName: string): number {
  const match = fileName.match(/^(\d+)\、/)
  if (match) {
    return parseInt(match[1], 10)
  }
  return Infinity // 如果没有匹配到罗马数字前缀，返回 Infinity 表示排在最后
}

/**
 * 比较两个文件名，根据它们的罗马数字前缀进行排序。
 * @param a 第一个文件名
 * @param b 第二个文件名
 * @returns 比较结果
 */
function compareByRomanPrefix(a: string, b: string): number {
  const numA = extractRomanPrefix(a)
  const numB = extractRomanPrefix(b)
  return numA - numB
}

// 递归函数来读取目录
export function readDirRecursively(
  basePath: string,
  relativePath: string = ""
): Promise<DirectoryItem[]> {
  return new Promise<DirectoryItem[]>((resolve, reject) => {
    fs.readdir(basePath, { withFileTypes: true }, (err, files) => {
      if (err) {
        reject(err)
        return
      }

      // 根据罗马数字前缀对文件进行排序
      files.sort((a, b) => compareByRomanPrefix(a.name, b.name))

      const items: DirectoryItem[] = []

      files.forEach((file) => {
        // 忽略隐藏文件
        if (file.name.startsWith(".")) return
        const parsedPath = path.parse(file.name)

        if (file.isDirectory()) {
          items.push({
            text: parsedPath.base, // 去掉扩展名
            collapsed: true,
            items: [],
          })
        } else {
          const relativeLinkPath = path.posix.join(relativePath, file.name)
          items.push({
            text: parsedPath.name, // 去掉扩展名
            link: `${prefix}${relativeLinkPath}`,
          })
        }
      })

      const promises = items
        .filter((item) => item.items)
        .map((item) => {
          const fullPath = path.join(basePath, item.text)
          return readDirRecursively(
            fullPath,
            path.posix.join(relativePath, item.text)
          ).then((children) => {
            item.items = children
          })
        })

      Promise.all(promises)
        .then(() => resolve(items))
        .catch(reject)
    })
  })
}
